package com.uenpay.util.common;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import android.view.View;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import static android.R.attr.path;

/**
 * 图像处理工具类
 */
public class PicUtil {

    private static final String TAG = "PicUtil";

    /**
     * 文件转换成Bitmap
     *
     * @param file
     * @return Bitmap
     * @throws IOException
     */
    public static Bitmap convertBitmap(File file) throws IOException {
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        FileInputStream fis = new FileInputStream(file.getAbsolutePath());
        int degree = readPictureDegree(file.getAbsolutePath());
        BitmapFactory.decodeFile(file.getAbsolutePath(), options);
        options.inSampleSize = calculateInSampleSize(options);

        options.inDither = false;
        options.inPurgeable = true;

        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeStream(fis, null, options);
        Bitmap newbitmap = rotaingImageView(degree, bitmap);
        fis.close();
        return newbitmap;
    }

    public static Bitmap loadImage(String imgPath) {
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inPreferredConfig = Config.RGB_565;// 图形的参数应该由两个字节来表示，应该是一种16位的位图
        opt.inPurgeable = true;// 设为True的话表示使用BitmapFactory创建的Bitmap,inPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收
        opt.inInputShareable = true;// 是否深拷贝
        // 获取资源图片
        imgPath = imgPath.replace("\n", "");
        imgPath = imgPath.trim();
        InputStream is = null;
        Bitmap bitmap = null;
        try {
            is = new FileInputStream(imgPath);
            bitmap = BitmapFactory.decodeStream(is, null, opt);// 直接调用 JNI >>
            // nativeDecodeAsset（）
            // 来完成decode，无需再使用java层的createBitmap，从而节省了java层的空间.
            if (is != null) {
                is.close();
            }
        } catch (FileNotFoundException e) {
            Log.e("ImageUtil", "文件：" + imgPath + "  找不到");
        } catch (IOException e) {
            Log.e("ImageUtil", e.getMessage());
        }
        return bitmap;
    }

    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    // 放大缩小图片
    public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidht = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidht, scaleHeight);
        Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

        bitmap.recycle();
        return newbmp;
    }

    /**
     * 旋转图片
     *
     * @param angle  角度
     * @param bitmap 原图片
     * @return Bitmap 转角度后的图片
     */
    public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
        // 旋转图片 动作
        Matrix matrix = new Matrix();
        ;
        matrix.postRotate(angle);
        Log.i(TAG, "angle2=" + angle);
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

    // 按照480X800的大小计算缩放比例
    private static int calculateInSampleSize(BitmapFactory.Options options) {
        // Raw height and width of image
        int reqHeight = 480;
        int reqWidth = 800;
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio;
        }
        return inSampleSize;
    }

    /**
     * 转换图片转换成圆形.
     *
     * @param bitmap 传入Bitmap对象
     * @return the bitmap
     */
    public static Bitmap toRoundBitmap(Bitmap bitmap) {
        if (bitmap == null) {
            return null;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float roundPx;
        float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
        if (width <= height) {
            roundPx = width / 2;
            top = 0;
            bottom = width;
            left = 0;
            right = width;
            height = width;
            dst_left = 0;
            dst_top = 0;
            dst_right = width;
            dst_bottom = width;
        } else {
            roundPx = height / 2;
            float clip = (width - height) / 2;
            left = clip;
            right = width - clip;
            top = 0;
            bottom = height;
            width = height;
            dst_left = 0;
            dst_top = 0;
            dst_right = height;
            dst_bottom = height;
        }

        Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect src = new Rect((int) left, (int) top, (int) right,
                (int) bottom);
        final Rect dst = new Rect((int) dst_left, (int) dst_top,
                (int) dst_right, (int) dst_bottom);
        final RectF rectF = new RectF(dst);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, src, dst, paint);
        return output;
    }

    // 上传图片后删除文件
    public static void DeleteFile(File file) {
        if (file == null) {
            return;
        }
        if (file.exists() == false) {
            return;
        } else {
            if (file.isFile()) {
                file.delete();
                return;
            }
            if (file.isDirectory()) {
                File[] childFile = file.listFiles();
                if (childFile == null || childFile.length == 0) {
                    file.delete();
                    return;
                }
                for (File f : childFile) {
                    DeleteFile(f);
                }
                file.delete();
            }
        }
    }

    /**
     * base64编码
     *
     * @param data
     * @return
     */
    public static String byteToBase64(byte[] data) {
        return Base64.encodeToString(data, Base64.DEFAULT);
    }

    /**
     * 将图片转为base64格式  默认Bitmap.CompressFormat.JPEG
     *
     * @param imgPath 图片路径
     * @return
     */
    public static String imgToBase64(String imgPath) {
        Bitmap bitmap = null;
        if (imgPath != null && imgPath.length() > 0) {
            FileDescriptor fd;
            try {
                fd = new FileInputStream(imgPath).getFD();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeFileDescriptor(fd, null, options);
                options.inSampleSize = calculateInSampleSize(options);
                options.inJustDecodeBounds = false;
                bitmap = BitmapFactory.decodeFile(imgPath, options);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        if (bitmap == null) {
            return null;
        }
        byte[] compressBytes = compressImage(CompressFormat.JPEG, bitmap);
        return Base64.encodeToString(compressBytes, Base64.DEFAULT);
    }

    /**
     * @param format  图片类型
     * @param imgPath 文件路径
     * @return
     */
    public static String imgToBase64(CompressFormat format, String imgPath) {
        Bitmap bitmap = null;
        if (imgPath != null && imgPath.length() > 0) {
            FileDescriptor fd;
            try {
                fd = new FileInputStream(imgPath).getFD();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeFileDescriptor(fd, null, options);
                options.inSampleSize = calculateInSampleSize(options);
                options.inJustDecodeBounds = false;
                bitmap = BitmapFactory.decodeFile(imgPath, options);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        if (bitmap == null) {
            return null;
        }
        byte[] compressBytes = compressImage(format, bitmap);
        return Base64.encodeToString(compressBytes, Base64.DEFAULT);
    }

    /**
     * 将图片转为base64格式  默认Bitmap.CompressFormat.JPEG
     *
     * @param bitmap_temp
     * @return
     */
    public static String imgToBase64(Bitmap bitmap_temp) {
        Bitmap bitmap = bitmap_temp;
        if (bitmap == null) {
            return null;
        }
        byte[] compressBytes = compressImage(CompressFormat.JPEG, bitmap);
        return Base64.encodeToString(compressBytes, Base64.DEFAULT);
    }

    /**
     * 将图片转为base64格式
     *
     * @param format      转化格式
     * @param bitmap_temp
     * @return
     */
    public static String imgToBase64(CompressFormat format, Bitmap bitmap_temp) {
        Bitmap bitmap = bitmap_temp;
        if (bitmap == null) {
            return null;
        }
        byte[] compressBytes = compressImage(format, bitmap);
        return Base64.encodeToString(compressBytes, Base64.DEFAULT);
    }

    public static byte[] compressImage(CompressFormat format, Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(CompressFormat.PNG, 100, baos);
        int options = 90;
        while (baos.toByteArray().length / 1024 > 100) {
            baos.reset();
            image.compress(format, options, baos);
            options -= 10;
            if (options <= 0) {
                break;
            }
        }
        return baos.toByteArray();
    }

    public static Bitmap getPicFromBytes(byte[] bytes,
                                         BitmapFactory.Options opts) {
        if (bytes != null)
            if (opts != null)
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.length,
                        opts);
            else
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        return null;
    }

    public static File getFileFromBytes(byte[] b, String outputFile) {
        BufferedOutputStream stream = null;
        File file = null;
        try {
            file = new File(outputFile);
            FileOutputStream fstream = new FileOutputStream(file);
            stream = new BufferedOutputStream(fstream);
            stream.write(b);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return file;
    }

    public static String getImgeHexString(FileInputStream fis) {
        String res = null;
        try {
            byte[] data = readStream(fis);
            res = byte2hex(data);
        } catch (FileNotFoundException e) {
            Log.e(TAG, e.getMessage() + "");
        } catch (Exception e) {
            Log.e(TAG, e.getMessage() + "");
        }
        return res;
    }

    public static String getImgeHexString(String filePath) {
        String res = null;
        try {
            byte[] data = readStream(new FileInputStream(new File(filePath)));
            res = byte2hex(data);
        } catch (FileNotFoundException e) {
            Log.e(TAG, e.getMessage() + "");
        } catch (Exception e) {
            Log.e(TAG, e.getMessage() + "");
        }
        return res;
    }

    public static byte[] readStream(InputStream inStream) throws Exception {
        byte[] buffer = new byte[1024];
        int len = -1;
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        byte[] data = outStream.toByteArray();
        outStream.close();
        inStream.close();
        return data;
    }

    // Bitmap → byte[]
    public static byte[] Bitmap2Bytes(Bitmap bm) {
        if (bm == null) {
            return null;
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // 可以是png 或者 jpg  png稍微大一些但清晰度高，jpg是有损压缩
        bm.compress(CompressFormat.JPEG, 100, baos);
        return baos.toByteArray();
    }

    // byte[] → Bitmap
    public static Bitmap Bytes2Bimap(byte[] b) {
        if (b != null && b.length != 0) {
            return BitmapFactory.decodeByteArray(b, 0, b.length);
        } else {
            return null;
        }
    }

    /**
     * 以最省内存的方式读取本地资源的图片
     */
    public static Bitmap readBitMap(Context context, int resId) {
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inPreferredConfig = Config.RGB_565;
        opt.inPurgeable = true;
        opt.inInputShareable = true;
        // 获取资源图片
        InputStream is = context.getResources().openRawResource(resId);
        return BitmapFactory.decodeStream(is, null, opt);
    }

    /**
     * 十六进制字符串转化为2进制
     */
    public static byte[] hex2byte(String s) {
        byte[] src = s.toLowerCase().getBytes();
        byte[] ret = new byte[src.length / 2];
        for (int i = 0; i < src.length; i += 2) {
            byte hi = src[i];
            byte low = src[i + 1];
            hi = (byte) ((hi >= 'a' && hi <= 'f') ? 0x0a + (hi - 'a')
                    : hi - '0');
            low = (byte) ((low >= 'a' && low <= 'f') ? 0x0a + (low - 'a')
                    : low - '0');
            ret[i / 2] = (byte) (hi << 4 | low);
        }
        return ret;
    }

    /**
     * 将二进制转化为16进制字符串
     *
     * @param b 二进制字节数组
     * @return String
     */
    public static String byte2hex(byte[] b) {
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                'B', 'C', 'D', 'E', 'F'};
        char[] out = new char[b.length * 2];
        for (int i = 0; i < b.length; i++) {
            byte c = b[i];
            out[i * 2] = Digit[(c >>> 4) & 0X0F];
            out[i * 2 + 1] = Digit[c & 0X0F];
        }
        return new String(out);
    }

    /**
     * 将bitmap保存到本地图库
     */
    public static String saveImageToGallery(Context context, Bitmap bmp) {
        // 首先保存图片
        File appDir = new File(Environment.getExternalStorageDirectory(), AppConfig.APP_LOCAL_FILE_NAME);
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 其次把文件插入到系统图库
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(),
                    file.getAbsolutePath(), fileName, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        // 最后通知图库更新
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + path)));
        return file.getPath();
    }

    public static Bitmap convertViewToBitmap(View view) {
        final boolean drawingCacheEnabled = true;
        view.setDrawingCacheEnabled(drawingCacheEnabled);
        view.buildDrawingCache(drawingCacheEnabled);
        final Bitmap drawingCache = view.getDrawingCache();
        Bitmap bitmap;
        if (drawingCache != null) {
            bitmap = Bitmap.createBitmap(drawingCache);
            view.setDrawingCacheEnabled(false);
        } else {
            bitmap = null;
        }
        return bitmap;
    }
}
